
在 React 16.8 版本以前,開發者使用不同的方法來撰寫 React 元件,這種方法涉及使用 class 和生命週期方法。
儘管如今開發者更傾向於使用函式元件和 Hooks,但了解如何使用 class 元件仍然是有價值的,因為我們可能會在舊的專案中遇到它們,或者需要將 class 元件轉換為函式元件。
首先,讓我們看一下使用 class 撰寫的 Counter 元件,使用 extends 繼承 React.Component 裡面提供的一些方法。
import React from "react";
class Counter extends React.Component {
  ...
}
React.Component 裡面提供的其中一個是 render 方法,每一個 class 元件都需要一個 render 方法用於返回 JSX。
class Counter extends React.Component {
  render() {
    return (
      <div>
        <button>-</button>
        <span>0</span>
        <button>+</button>
      </div>
    );
  }
}
當使用 class 元件時,要在 constructor 中使用 super 方法獲取 props:
class Counter extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <div>
        <button>-</button>
        <span>0</span>
        <button>+</button>
      </div>
    );
  }
}
要定義狀態,需要在 constructor 中定義 this.state,在 JSX 中想要訪問 state 的值,必須使用 this.state。
class Counter extends React.Component {
  constructor(props) {
    super(props);
	// 定義狀態
    this.state = {
      count: 5
    };
  }
  render() {
    return (
      <div>
        <button>-</button>
		// 使用 state 裡面的 count
        <span>{this.state.count}</span>
        <button>+</button>
      </div>
    );
  }
}
可以在 class 中撰寫事件處理函式,但要注意在 JSX 內部執行的函式會失去與 this 關鍵字的綁定。
class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 5
    };
  }
  handleDecrement() {
	// undefined
    console.log(this);
  }
  render() {
    return (
      <div>
        <button onClick={this.handleDecrement}>-</button>
        <span>{this.state.count}</span>
        <button>+</button>
      </div>
    );
  }
}
因此,我們可以在 constructor 裡面將 this 綁定到 handleDecrement 函式,此時的 this 就會是 Counter 實例。
class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 5
    };
    this.handleDecrement = this.handleDecrement.bind(this);
  }
  handleDecrement() {
	// Counter 實例
    console.log(this);
  }
  render() {
    return (
      <div>
        <button onClick={this.handleDecrement}>-</button>
        <span>{this.state.count}</span>
        <button>+</button>
      </div>
    );
  }
}
我們可以透過 setState 這個方法來更新狀態的值,setState 接收一個 callback function,該函式提供當前狀態的值,讓我們可以根據當前狀態計算新的值。
class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 5
    };
    this.handleDecrement = this.handleDecrement.bind(this);
  }
  handleDecrement() {
	// 方法一:直接更新狀態
	this.setState({
	  count: 10
	});
	// 方法二:基於當前狀態更新
    this.setState((curState) => {
	  // 返回我們希望的值
      return {
        count: curState.count - 1
      };
    });
  }
  render() {
    return (
      <div>
        <button onClick={this.handleDecrement}>-</button>
        <span>{this.state.count}</span>
        <button>+</button>
      </div>
    );
  }
}
在 React 16.8 版本以前,開發者使用 class 來撰寫 React 元件,雖然函式元件和 Hooks 已經成為目前的主流開發方式,但了解 class 的寫法也是十分重要的。